﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;

namespace CoreLims.Models.CoreLims
{
    using SampleDefinition = SampleSampleDefinition;

    public static class SampleSampleDefinitionExtension
    {
        public static List<SampleDefinition> getSampleDefinitionList(this SampleDefinition spdf, CoreLimsContext dbContext) => dbContext.SampleDefinition.ToList();

        /// <summary>
        /// 根据 样品类型 获取样品数据
        /// </summary>
        /// <param name="Classification"></param>
        /// <returns></returns>
        public static List<SampleDefinition> getSampleDefinitionListByClassification(this SampleDefinition spdf, CoreLimsContext dbContext, string Classification) => 
            dbContext.SampleDefinition.Where(s => s.Classification == Classification).OrderBy(x => x.Name).ToList();

        /// <summary>
        /// 根据 样品分类 获取样品数据
        /// </summary>
        /// <returns></returns>
        public static List<SampleDefinition> getSampleDefinitionListByGenricClass(this SampleDefinition spdf, CoreLimsContext dbContext, string GenricClass) =>
            dbContext.SampleDefinition.Where(s => s.GenricClass == GenricClass).OrderBy(x => x.Name).ToList();

        /// <summary>
        /// 根据 样品类型、样品分类，获取样品数据
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="Classification">样品类型</param>
        /// <param name="GenricClass">样品分类</param>
        /// <returns></returns>
        public static List<SampleDefinition> getSampleDefinitionListClassAndGenric(this SampleDefinition spdf, CoreLimsContext dbContext, string Classification, string GenricClass)
        {
            if (Classification == "全部")
                return dbContext.SampleDefinition.OrderBy(x => x.Name).ToList();

            if (string.IsNullOrEmpty(GenricClass))
                return dbContext.SampleDefinition.Where(s => s.Classification == Classification).OrderBy(x => x.Name).ToList();
            else
                return dbContext.SampleDefinition.Where(s => s.Classification == Classification && s.GenricClass == GenricClass).OrderBy(x => x.Name).ToList();
        }

        public static List<SampleDefinition> getSampleDefinition(this SampleDefinition spdf, CoreLimsContext dbContext) => 
            dbContext.SampleDefinition.ToList().OrderBy(x => x.Name).ToList();

        public static SampleDefinition getSampleDefinition(this SampleDefinition spdf, CoreLimsContext dbContext, string Id) => 
            dbContext.SampleDefinition.FirstOrDefault(m => m.Id == Id);

        /// <summary>
        /// 根据 名称 模糊查询
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        public static List<SampleDefinition> getSampleDefinitionByName(this SampleDefinition spdf, CoreLimsContext dbContext, string Name) => 
            dbContext.SampleDefinition.Where(m => m.Name.Contains(Name)).ToList().OrderBy(x => x.Name).ToList();

        public static string AddSampleDefinition(this SampleDefinition spdf, CoreLimsContext dbContext)
        {
            spdf.Id = SAMPLE._newId();
            dbContext.Add(spdf);
            dbContext.SaveChanges();
            return "样品添加成功！";
        }

        /// <summary>
        /// 更新样品
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="dbContext"></param>
        /// <returns></returns>
        public static string UpdateSampleDefinition(this SampleDefinition spdf, CoreLimsContext dbContext)
        {
            SampleDefinition Spdf = SAMPLE.SampleDefinition.getSampleDefinition(dbContext, spdf.Id);
            Spdf.Copy(spdf);

            dbContext.Update(Spdf);
            dbContext.SaveChanges();
            return "样品信息更新成功！";
        }

        /// <summary>
        /// 删除样品定义
        /// </summary>
        /// <param name="Spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public static string DeleteSampleDefinition(this SampleDefinition Spdf, CoreLimsContext dbContext, string Id)
        {
            SampleDefinition spdf = SAMPLE.SampleDefinition.getSampleDefinition(dbContext, Id);
            var list = dbContext.Relation.Where(s => s.SourceTabName == "SampleDefinition" && s.SourceId == spdf.Id).ToList();

            foreach (var item in list)  // 删除该样品的所有关系
                dbContext.Remove(item);

            dbContext.Remove(spdf);
            dbContext.SaveChanges();
            return "样品删除成功！";
        }

        public static string CopySampleDefinition(this SampleDefinition Spdf, CoreLimsContext dbContext, string Id)
        {
            SampleDefinition spdf = SAMPLE.SampleDefinition.getSampleDefinition(dbContext, Id);
            var list = dbContext.Relation.Where(s => s.SourceTabName == "SampleDefinition" && s.SourceId == spdf.Id).ToList();

            var newspdf = new SampleDefinition();
            newspdf.Copy(spdf);
            newspdf.Name = spdf.Name + "复制";
            dbContext.SampleDefinition.Add(newspdf);

            foreach (var item in list)
            {
                var relation = new SampleRelation();
                relation.Copy(item);
                relation.SourceId = newspdf.Id;
                dbContext.Relation.Add(relation);
            }
            
            dbContext.SaveChanges();
            return "样品复制成功！";
        }

        /// <summary>
        /// 更新 所属实验室 和 工作组
        /// </summary>
        /// <param name="Spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="Id"></param>
        /// <param name="Site">所属实验室</param>
        /// <param name="Group">工作组</param>
        /// <returns></returns>
        public static string UpdateSampleDefinitionSiteAndGroup(this SampleDefinition Spdf, CoreLimsContext dbContext, string Id, string Site, string Group)
        {
            SampleDefinition spdf = SAMPLE.SampleDefinition.getSampleDefinition(dbContext, Id);

            spdf.Site = Site;
            spdf.Group = Group;

            dbContext.Update(spdf);
            dbContext.SaveChanges();
            return "实验室和工作组更新成功！";
        }

        /// <summary>
        /// 更新 关联物料
        /// </summary>
        /// <param name="Spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="Id"></param>
        /// <param name="MaterialId"></param>
        /// <returns></returns>
        public static string UpdateSampleDefinitionMaterialId(this SampleDefinition Spdf, CoreLimsContext dbContext, string Id, string MaterialId)
        {
            SampleDefinition spdf = SAMPLE.SampleDefinition.getSampleDefinition(dbContext, Id);
            spdf.MaterialId = MaterialId;

            dbContext.Update(spdf);
            dbContext.SaveChanges();
            return "关联物料更新成功！";
        }

        /// <summary>
        /// 更新 关联的流程ID
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="Id"></param>
        /// <param name="WorkFlowId"></param>
        /// <returns></returns>
        public static string UpdateSampleDefinitionWorkFlowId(this SampleDefinition spdf, CoreLimsContext dbContext, string Id, string WorkFlowId)
        {
            SampleDefinition Spdf = SAMPLE.SampleDefinition.getSampleDefinition(dbContext, Id);
            spdf.WorkFlowId = WorkFlowId;

            dbContext.Update(Spdf);
            dbContext.SaveChanges();
            return "流程ID更新成功！";
        }

        /// <summary>
        /// 更新 跳过流程步骤
        /// </summary>
        /// <param name="sample"></param>
        /// <param name="dbContext"></param>
        /// <param name="Id"></param>
        /// <param name="SkipSequence"></param>
        /// <returns></returns>
        public static string UpdateSkipSequence(this SampleDefinition spdf, CoreLimsContext dbContext, string Id, string SkipSequence)
        {
            var sd = SAMPLE.SampleDefinition.getSampleDefinition(dbContext, Id);
            sd.SkipSequence = SkipSequence;

            dbContext.Update(sd);
            dbContext.SaveChanges();
            return "流程步骤更新成功！";
        }

        /// <summary>
        /// 复制记录内容，ID不复制
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="other"></param>
        /// <returns></returns>
        public static SampleDefinition Copy(this SampleDefinition spdf, SampleDefinition other)
        {
            spdf.Name = other.Name;
            spdf.Description = other.Description;
            spdf.Classification = other.Classification;
            spdf.GenricClass = other.GenricClass;
            spdf.Site = other.Site;
            spdf.Group = other.Group;
            spdf.SamplingPoint = other.SamplingPoint;
            //spdf.InventoryId = other.InventoryId;
            //spdf.MaterialId = other.MaterialId;
            //spdf.EquipmentTypeList = other.EquipmentTypeList;
            spdf.WorkFlowId = other.WorkFlowId;
            spdf.WorkFlowName = other.WorkFlowName;
            spdf.ReportName = other.ReportName;
            spdf.DefaultNumber = other.DefaultNumber;

            return spdf;
        }

        /// <summary>
        /// 根据ID从关系表中获得与该样品关联的分析项列表
        /// </summary>
        /// <param name="spdfId"></param>
        /// <returns></returns>
        public static IQueryable<object> getRelationAnalytes(this SampleDefinition spdf, CoreLimsContext dbcontext, string SampleDefinitionId)
        {
            var list = dbcontext.Relation.Where(s => s.SourceId == SampleDefinitionId && s.SourceTabName == "SampleDefinition" && s.IncludedTabName == "Analytes")
                .Select(s => new { s.IncludedId })
                .ToArray();

            string[] array = new string[list.Length];
            for (int i = 0; i < list.Length; i++)
            {
                array[i] = list[i].IncludedId;
            }

            var analist = from analyte in dbcontext.Analyte
                          join relation in dbcontext.Relation on analyte.Id equals relation.IncludedId
                          where (array.Contains(analyte.Id) && relation.SourceId == SampleDefinitionId && 
                            relation.SourceTabName == "SampleDefinition" && relation.IncludedTabName == "Analytes")
                           select new
                           {
                               relation.Id,
                               analyte.Code,
                               analyte.Name,
                               analyte.Classification,
                               analyte.Description,
                               analyte.ResultModel,
                               analyte.RoundingOff,
                               analyte.Units,
                               analyte.DefaultSpecName,
                               analyte.Assist,
                               relation.Repeat,
                               relation.IncludedId, // 这个ID就是Analyte表的ID
                           };

            return analist;
        }

        /// <summary>
        /// 添加样品定义所包含的 分析项
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="SampleDefinitionId">样品定ID</param>
        /// <param name="AnalyteID">分析项ID</param>
        /// <returns></returns>
        public static string AddRelationAanylte(this SampleDefinition spdf, CoreLimsContext dbContext, string SampleDefinitionId, string AnalyteID)
        {
            var rel = dbContext.Relation.FirstOrDefault(s => s.SourceId == SampleDefinitionId && s.SourceTabName == "SampleDefinition" 
                && s.IncludedTabName == "Analytes" && s.IncludedId == AnalyteID);

            if(rel != null)
                return "样品已经包含此分析项！";

            rel = new SampleRelation();
            rel.SourceId = SampleDefinitionId;
            rel.SourceTabName = "SampleDefinition";
            rel.IncludedId = AnalyteID;
            rel.IncludedTabName = "Analytes";
            rel.Repeat = 1;

            dbContext.Add(rel);
            dbContext.SaveChanges();
            return "样品包含的分析项添加成功！";
        }

        /// <summary>
        /// 删除样品定义中包含的 分析项
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="SampleDefinitionId">样品定ID</param>
        /// <param name="AnalyteID">分析项ID</param>
        /// <returns></returns>
        public static string DelteRelationAanylte(this SampleDefinition spdf, CoreLimsContext dbContext, string RelationId)
        {
            var rel = dbContext.Relation.FirstOrDefault(s => s.Id == RelationId);

            if (rel == null)
                return "未找到该包含关系！";

            dbContext.Remove(rel);
            dbContext.SaveChanges();
            return "样品包含的分析项删除成功！";
        }

        /// <summary>
        /// 根据ID从关系表中获得与该样品关联的测试列表
        /// </summary>
        /// <param name="spdfId"></param>
        /// <returns></returns>
        public static IQueryable<object> getRelationTestDefinition(this SampleDefinition spdf, CoreLimsContext dbcontext, string SampleDefinitionId)
        {
            var list = dbcontext.Relation.Where(s => s.SourceId == SampleDefinitionId && s.SourceTabName == "SampleDefinition" && s.IncludedTabName == "TestDefinition")
                .Select(s => new { s.IncludedId })
                .ToArray();

            string[] array = new string[list.Length];
            for (int i = 0; i < list.Length; i++)
            {
                array[i] = list[i].IncludedId;
            }

            var tdlist = from tdf in dbcontext.TestDefinition
                          join relation in dbcontext.Relation on tdf.Id equals relation.IncludedId
                          where (array.Contains(tdf.Id) && relation.SourceId == SampleDefinitionId &&
                            relation.SourceTabName == "SampleDefinition" && relation.IncludedTabName == "TestDefinition")
                          select new
                          {
                              relation.Id,
                              tdf.TestName,
                              tdf.FirstGroup,
                              tdf.SecondGroup,
                              tdf.Description,
                              tdf.Version,
                              relation.Repeat,
                              relation.IncludedId, // 这个ID就是TestDefinition表的ID
                          };

            return tdlist;
        }

        /// <summary>
        /// 添加样品定义所包含的 测试项
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="SampleDefinitionId">样品定ID</param>
        /// <param name="AnalyteID">分析项ID</param>
        /// <returns></returns>
        public static string AddRelationTestDefinition(this SampleDefinition spdf, CoreLimsContext dbContext, string SampleDefinitionId, string TestDefinitionId)
        {
            var rel = dbContext.Relation.FirstOrDefault(s => s.SourceId == SampleDefinitionId && s.SourceTabName == "SampleDefinition"
                && s.IncludedTabName == "TestDefinition" && s.IncludedId == TestDefinitionId);

            if (rel != null)
                return "样品已经包含该项测试！";

            rel = new SampleRelation();
            rel.Id = SAMPLE._newId();
            rel.SourceId = SampleDefinitionId;
            rel.SourceTabName = "SampleDefinition";
            rel.IncludedId = TestDefinitionId;
            rel.IncludedTabName = "TestDefinition";
            rel.Repeat = 1;

            dbContext.Add(rel);
            dbContext.SaveChanges();
            return "样品包含的测试添加成功！";
        }

        /// <summary>
        /// 删除样品定义中包含的 测试项
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="SampleDefinitionId">样品定ID</param>
        /// <param name="AnalyteID">分析项ID</param>
        /// <returns></returns>
        public static string DelteRelationTestDefinition(this SampleDefinition spdf, CoreLimsContext dbContext, string RelationId)
        {
            var rel = dbContext.Relation.FirstOrDefault(s => s.Id == RelationId);

            if (rel == null)
                return "未找到该包含关系！";

            dbContext.Remove(rel);
            dbContext.SaveChanges();
            return "样品包含的测试项删除成功！";
        }

        /// <summary>
        /// 根据ID从关系表中获得与该样品关联的指标集列表
        /// </summary>
        /// <param name="spdfId"></param>
        /// <returns></returns>
        public static IQueryable<object> getRelationSpecCollection(this SampleDefinition spdf, CoreLimsContext dbcontext, string SampleDefinitionId)
        {
            var list = dbcontext.Relation
                .Where(s => s.SourceId == SampleDefinitionId && s.SourceTabName == "SampleDefinition" && s.IncludedTabName == "SpecCollection")
                .Select(s => new { s.IncludedId })
                .ToArray();

            string[] array = new string[list.Length];
            for (int i = 0; i < list.Length; i++)
            {
                array[i] = list[i].IncludedId;
            }

            var tdlist = from spec in dbcontext.Spec
                         join relation in dbcontext.Relation on spec.Id equals relation.IncludedId
                         where (array.Contains(spec.Id) && relation.SourceId == SampleDefinitionId &&
                           relation.SourceTabName == "SampleDefinition" && relation.IncludedTabName == "SpecCollection")
                         select new
                         {
                             relation.Id,
                             spec.Code,
                             spec.Name,
                             spec.FirstGroup,
                             spec.SecondGroup,
                             spec.Description,
                             spec.Version,
                             relation.Repeat,
                             relation.IncludedId, // 这个ID就是 SpecCollection 表的ID
                         };

            return tdlist;
        }

        /// <summary>
        /// 添加样品定义所包含的 指标集
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="SampleDefinitionId"></param>
        /// <param name="TestDefinitionId"></param>
        /// <returns></returns>
        public static string AddRelationSpecCollection(this SampleDefinition spdf, CoreLimsContext dbContext, string SampleDefinitionId, string SpecCollectionId)
        {
            var rel = dbContext.Relation.FirstOrDefault(s => s.SourceId == SampleDefinitionId && s.SourceTabName == "SampleDefinition"
                && s.IncludedTabName == "SpecCollection" && s.IncludedId == SpecCollectionId);

            if (rel != null)
                return "样品已经包含该指标集！";

            rel = new SampleRelation();
            rel.Id = SAMPLE._newId();
            rel.SourceId = SampleDefinitionId;
            rel.SourceTabName = "SampleDefinition";
            rel.IncludedId = SpecCollectionId;
            rel.IncludedTabName = "SpecCollection";

            var list = dbContext.Relation.Where(s => s.SourceId == SampleDefinitionId && s.SourceTabName == "SampleDefinition"
                && s.IncludedTabName == "SpecCollection" && s.IncludedId != null).ToList().Count;
            if (list == 0) // 第一项设为默认值
                rel.Repeat = 1;
            else
                rel.Repeat = null;


            dbContext.Add(rel);
            dbContext.SaveChanges();
            return "样品包含的指标集添加成功！";
        }

        /// <summary>
        /// 删除样品定义中包含的 指标集
        /// </summary>
        /// <param name="spdf"></param>
        /// <param name="dbContext"></param>
        /// <param name="SampleDefinitionId">样品定ID</param>
        /// <param name="AnalyteID">分析项ID</param>
        /// <returns></returns>
        public static string DelteRelationSpecCollection(this SampleDefinition spdf, CoreLimsContext dbContext, string RelationId)
        {
            var rel = dbContext.Relation.FirstOrDefault(s => s.Id == RelationId);
            if (rel == null)
                return "未找到该包含关系！";

            var temp = dbContext.Relation.FirstOrDefault(s => s.SourceId == rel.SourceId && s.SourceTabName == "SampleDefinition"
                && s.IncludedTabName == "SpecCollection" && s.IncludedId != rel.IncludedId);
            if (temp != null) //删除当前关系时，如果还包含其它指标集，则找一项设为默认值
            {
                temp.Repeat = 1;
                dbContext.Update(temp);
            }

            dbContext.Remove(rel);
            dbContext.SaveChanges();
            return "样品包含的指标集删除成功！";
        }

    }

}
